package cn.z2huo.usercenter.authentication.app.interceptor;

import cn.z2huo.usercenter.authentication.model.vo.login.test.UserLoginReqVO;
import cn.z2huo.usercenter.util.RedisKeyGenerateUtils;
import com.fasterxml.jackson.databind.json.JsonMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.redisson.api.RAtomicLong;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.BufferedReader;
import java.time.Duration;

/**
 * <p>
 *
 * @author z2huo
 */
@Component
@RequiredArgsConstructor
public class FixedWindowLimitLoginInterceptor implements HandlerInterceptor {

    private final RedissonClient redissonClient;

    private final JsonMapper jsonMapper;

    private static final int LIMIT_COUNT = 5;

    private static final Duration LIMIT_TIME_DURATION = Duration.ofSeconds(60);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        StringBuilder sb = new StringBuilder();
        try (BufferedReader reader = request.getReader()) {
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        }

//        String reqString = request.getReader().lines().collect(Collectors.joining());
        String reqString = sb.toString();

        UserLoginReqVO reqVO = jsonMapper.readValue(reqString, UserLoginReqVO.class);

        String redisKey = RedisKeyGenerateUtils.AUTHENTICATION_APP.generateMd5("user-login-fixed", reqVO.getUserCode());

        RAtomicLong atomicLong = redissonClient.getAtomicLong(redisKey);
        long count = atomicLong.getAndIncrement();
        if (count == 1) {
            atomicLong.expire(LIMIT_TIME_DURATION);
        }
        if (count >= LIMIT_COUNT) {
            return false;
//            throw new RuntimeException("限制时间内登陆次数过多，请稍后再试");
        }

        return true;
    }
}
